#pragma once

#include <assert.h>
#include <stdint.h>
#include <vector>
#include <string>
#include <cstring>

#define BUFFER_DEFAULT_SIZE 1024
class Buffer
{
private:
    //  1. 避免手动内存管理  2. 为什么不用string string 的 \0 截断问题：
    //         string 的 c_str() 和 data()（C++11 前）返回的字符串以 \0 终止，若数据中包含 \0，会导致截断
    std::vector<char> _buffer;
    uint64_t _read_idx;  //读偏移量
    uint64_t _write_idx; // 写偏移量

public:
    Buffer();
    // 1. 获取起始地址
    char *Begin() const;

    // 2. 获取当前写入位置
    char *WritePosition();

    // 3. 获取当前读取位置
    char *ReadPosition();

    // 4. 获取缓冲区末尾的空闲空间大小
    uint64_t TailIdSize();

    // 5. 获取头部空闲空间大小
    uint64_t HeadIdSize();

    // 6. 可读数据大小
    uint64_t ReadAbleSize();

    // 7. 移动读偏移量
    void MoveReadOffset(uint64_t len);

    // 8. 移动写偏移量
    void MoveWriteOffset(uint64_t len);

    // 9. 取保可写空间足够，不够就自动扩容
    void EnsureWriteSpace(uint64_t len);

    /*                 写操作                     */

    void Write(const void *data, uint64_t len);
    void WriteAndPush(const void *data, uint64_t len);

    void WriteString(const std::string &data);
    void WriteStringAndPush(const std::string &data);

    void WriteBuffer(Buffer &data);
    void WriteBufferAndPush(Buffer &data);

    /*                 读操作                                           */

    void Read(void *buf, uint64_t len);
    void ReadAndPop(void *buf, uint64_t len);

    std::string ReadAsString(uint64_t len);
    std::string ReadAsStringAndPop(uint64_t len);

    // 查找回车字符的地址
    char *FindCRLF();

    // 获取HTTP协议一行的数据
    std::string GetLine();
    std::string GetLineAndPop();

    // 清空缓冲区
    void Clear();
};
